package cn.sdormitory.wx.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.sdormitory.common.utils.StringUtils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class WXUtil {

    @Value("${oauth.wx.appid}")
    private String appid;

    @Value("${oauth.wx.secret}")
    private String secret;

    //转换工具类
    @Autowired
    HttpClientUtils httpClientUtils;



    @Autowired
    StringRedisTemplate redisTemplate;
//    @Resource
//    RestTemplate restTemplate;


    /**
     * 获取用户openId
     * @param code
     * @return
     */
    public Map wxToken(String code){
            //通过code换取网页授权access_token
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid +
                    "&secret=" + secret +
                    "&code=" + code +
                    "&grant_type=authorization_code";


            try {
                JSONObject jsonObject = httpClientUtils.doGet(url);

                String openid = jsonObject.getString("openid");

                String access_token = jsonObject.getString("access_token");
                System.out.println("七月");
                System.out.println(access_token);
                System.out.println(openid);

                url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token +
                        "&openid=" + openid +
                        "&lang=zh_CN";

                //拉取用户信息
                JSONObject userInfoJson = httpClientUtils.doGet(url);

                Map<String,Object> map = new HashMap<>();
                map.put("openid",openid);
                map.put("access_token",access_token);
                map.put("userInfoJson",userInfoJson);

                System.out.println(userInfoJson);
                return map;

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }


    /**
     * 获取token
     * @return
     */
    public String gainToken(){
            // 先从缓存查看有没有
            String appletToken = redisTemplate.opsForValue().get("access_token");
            if (!StringUtils.isBlank(appletToken)) {
                return appletToken;
            }
            // TODO
            //设置查询参数与请求url
            MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
            queryParams.add("appid", appid);
            queryParams.add("secret", secret);

            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
            UriComponentsBuilder tokenBuilder = UriComponentsBuilder.fromHttpUrl(url).queryParams(queryParams);

            System.out.println("joker");
            System.out.println(tokenBuilder);
            //获取token
            RestTemplate restTemplate = new RestTemplate();
            String tokenResult = restTemplate.getForObject(tokenBuilder.toUriString(), String.class);
            cn.hutool.json.JSONObject tokenObject = JSONUtil.parseObj(tokenResult);

            String access_token = tokenObject.getStr("access_token");

            if(StringUtils.isBlank(access_token)){
                throw new RuntimeException("小程序token获取失败，" + tokenObject.getStr("errmsg"));
            }
            //将token存到redis，有效期100分钟。官方接口返回的token有效期120分钟
            redisTemplate.opsForValue().set("access_token", access_token);
            redisTemplate.expire("access_token", 100, TimeUnit.MINUTES);

            return access_token;
        }


    /**
     * 发送模板信息
     * @param openId        用户openid
     * @param template_id   模板id
     * @param data          推送内容
     * @param pagepath      跳转小程序页面
     * @return
     */
    public cn.hutool.json.JSONObject sendInfo(String openId,String template_id, Map<String, Object> data,String pagepath) {

        cn.hutool.json.JSONObject jsonObject = null;

        try {
            String access_token = gainToken();

            //发送消息
            String tokenUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token;

            Map<String,Object> map = new HashMap<>();

            map.put("touser",openId);
            map.put("template_id",template_id);
            map.put("lang", "zh_CN");
            map.put("miniprogram_state", "formal");
            JSONObject json_miniprogram = new JSONObject();
            json_miniprogram.put("appid", "wxa1e5577fa5b381ff");
            json_miniprogram.put("pagepath",pagepath);
            map.put("miniprogram", json_miniprogram);
            map.put("data",data);
            //将数据转换为json字符串
            String jsonString = JSONObject.toJSONString(map);
            //将数据传入HTTP请求主体
            HttpEntity<String> request = new HttpEntity<>(jsonString);

            HttpRequest httpRequest = HttpUtil.createPost(tokenUrl);
            httpRequest.body(jsonString);
            String body = httpRequest.execute().body();
//            RestTemplate restTemplate = new RestTemplate();
//
//            String forObject = restTemplate.postForObject(tokenUrl, request, String.class);
            jsonObject = JSONUtil.parseObj(body);

            if(!"0".equals(jsonObject.get("errcode").toString())){
                throw new RuntimeException("发送订阅消息失败，" + jsonObject.get("errmsg"));
            }

        } catch (RestClientException e) {
            log.error(e.getMessage());
        }
        return jsonObject;

    }


}
